// DlgCountMonth.cpp : implementation file
//

#include "stdafx.h"
#include "finance.h"
#include "CDataFile.h"
#include "financedef.h"
#include "DlgCountMonth.h"

#include "MainFrm.h"
#include "FinanceDoc.h"
#include "FinanceView.h"
#include "SearchView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


extern CFinanceApp theApp;       

/////////////////////////////////////////////////////////////////////////////
// CDlgCountMonth dialog


CDlgCountMonth::CDlgCountMonth(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgCountMonth::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgCountMonth)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_lYear = 0;
	m_pSearchView = NULL;
	m_chMonth[0] = 0;
}


void CDlgCountMonth::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgCountMonth)
	DDX_Control(pDX, IDC_ED_DATERANGE, m_edDaterange);
	DDX_Control(pDX, IDC_ED_COUNTINFO, m_edCountinfo);
	DDX_Control(pDX, IDOK, m_btnOk);
	DDX_Control(pDX, IDC_BTN_TOSEARCH, m_btnSaveSearch);
	DDX_Control(pDX, IDC_CMB_FLOW, m_cmbFlow);
	DDX_Control(pDX, IDC_CMB_PURPOSE, m_cmbPurpose);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgCountMonth, CDialog)
	//{{AFX_MSG_MAP(CDlgCountMonth)
	ON_NOTIFY(NSCS_SELECTEDITEM, IDC_CST_MONTHCHART, OnChartSelectedItem)
	ON_CBN_SELCHANGE(IDC_CMB_FLOW, OnSelchangeCmbFlow)
	ON_CBN_SELCHANGE(IDC_CMB_PURPOSE, OnSelchangeCmbPurpose)
	ON_BN_CLICKED(IDC_BTN_TOSEARCH, OnBtnToSearchView)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgCountMonth message handlers

// 
// 
//--------------------------------------------------------------
BOOL CDlgCountMonth::OnInitDialog() 
{
	_variant_t		var;
	CString			csTmp;
	CString			csSQL;
	CHAR			chTmp[50] = { 0 };

	
	CDialog::OnInitDialog();
	
	m_btnOk.SetIcon(IDI_EYEON, IDI_EYEOFF);
	m_btnSaveSearch.SetIcon(IDI_LEDON, IDI_LEDOFF);

	// set date range info
	sprintf( chTmp, " Month count of %d ", m_lYear );
	m_edDaterange.SetWindowText( chTmp );
	
	// Subclassing
	m_chartMonth.SubclassDlgItem( IDC_CST_MONTHCHART, this );
	m_chartMonth.PrepareColors(CNSChartCtrl::SimpleColors);
	m_chartMonth.SetChartStyle( NSCS_BAR );
	m_chartMonth.EnableBarGridLines( TRUE );
	m_chartMonth.SetPieceValueFormat( NSCVAL_ABSVAL );
	
	
	//set back color and text color
	m_edDaterange.SetBackColor(RGB(255,255,255));
	m_edDaterange.SetTextColor(RGB(0,0,128));
	m_edCountinfo.SetBackColor(RGB(255,255,255));
	m_edCountinfo.SetTextColor(RGB(0,0,255));
	
	// <> RecordSet and _CommandPtr init
	m_pRecordset.CreateInstance(__uuidof(Recordset));
	m_pCommand.CreateInstance(__uuidof(Command));
	m_pCommand->ActiveConnection = theApp.m_pConnection.GetInterfacePtr();
	
	
	// <> Fill ComboBox flowclass
	try
	{
		m_pRecordset->Open("SELECT * FROM Flowclass",   
			theApp.m_pConnection.GetInterfacePtr(),	 // Get the Ptr of connect lib
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	m_cmbFlow.ResetContent();
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			//AfxMessageBox("Table is NULL");
			return TRUE;
		}
		
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Classname"); // txt
			if(var.vt != VT_NULL)
				csTmp = (LPCSTR)_bstr_t(var);
			
			m_cmbFlow.AddString( csTmp );
			
			m_pRecordset->MoveNext();
		}
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	m_cmbFlow.SetCurSel( 0 );
	m_pRecordset->Close();
	
	
	// <> Fill ComboBox Purpose
	OnSelchangeCmbFlow();


	UpdateData( FALSE );
	
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

// 
//--------------------------------------------------------------
CDlgCountMonth::~CDlgCountMonth()
{
	if( m_pRecordset != NULL )
	{
		if( m_pRecordset->State )
			m_pRecordset->Close();
		m_pRecordset = NULL;
	}
}

// 
//--------------------------------------------------------------
void CDlgCountMonth::OnSelchangeCmbFlow() 
{
	_variant_t		var;
	CString			csTmp;
	CString			csSQL;
	

	// Disable Search BTN when not focus in one label
	m_btnSaveSearch.EnableWindow( FALSE );
	
	// <> Fill ComboBox Purpose
	m_cmbFlow.GetLBText( m_cmbFlow.GetCurSel(), csTmp );
	
	csSQL = "SELECT Usename FROM Purpose WHERE Flowclass='" + csTmp + "' ORDER BY Usename ASC";
	var = csSQL;
	try
	{
		m_pRecordset->Open( var,					// const _variant_t & Source
			theApp.m_pConnection.GetInterfacePtr(),	// Get the Ptr of connect lib
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	m_cmbPurpose.ResetContent();
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			//AfxMessageBox("Table is NULL");
			return ;
		}
		
		m_cmbPurpose.AddString( "All" );
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Usename"); // txt
			if(var.vt != VT_NULL)
				csTmp = (LPCSTR)_bstr_t(var);
			
			m_cmbPurpose.AddString( csTmp );
			
			m_pRecordset->MoveNext();
		}
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	m_cmbPurpose.SetCurSel( 0 );
	m_pRecordset->Close();


	// <> Count and into Chart
	CountOneYear();
	
	// ! Must after CountOneYear(), 
	// because using CNSChartCtrl::GetItemCount() in CountOutline()
	// <> info into readonly-edit
	CountOutline();
	
	// <> Do below to refresh ChartCtrl after "no values" to "has values" 
	//	  Otherwise ChartCtrl will not repaint() !
	m_chartMonth.SetChartStyle( NSCS_BAR );
}

// 
// 
//--------------------------------------------------------------
void CDlgCountMonth::CountOneYear()
{
	_RecordsetPtr	pRecSet;
	_variant_t		var;
	LONG			lCount = 0;
	DOUBLE			dbSum = 0;
	CHAR			chSQL[INI_MAX_BUFLEN+100] = { 0 };
	CHAR			chDate[50] = { 0 };
	CHAR			chDateBeg[50] = { 0 };
	CHAR			chDateEnd[50] = { 0 };
	CHAR			chDateRange[50] = { 0 };
	CString			csTmp, csTitle = "Every month of ";
						//	Month : 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12
	INT			i,	iMdays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };


	// <> reset
	m_chartMonth.Empty();

	m_cmbPurpose.GetLBText( m_cmbPurpose.GetCurSel(), csTmp );
	csTitle += csTmp;
	m_chartMonth.SetTitle( csTitle );
	
	if( ( m_lYear % 4 == 0 && m_lYear % 100 != 0 ) 
		|| ( m_lYear % 400 == 0 ) )
	{
		// leap year, max date is 29
		iMdays[2]++;
	}

	sprintf( chDate, "%d", m_lYear );

	// <>Count by every normal month
	for( i=1; i<=12; i++ )
	{
		// compose month range
		if( wtkGetSysLanguage() == WTK_BIG5 ) 
		{
			sprintf( chDateRange, "%s/%d", chDate, i );
			sprintf( chDateBeg, "%s/%d/1", chDate, i );
			sprintf( chDateEnd, "%s/%d/%d", chDate, i, iMdays[i] );
		}
		else
		{
			sprintf( chDateRange, "%s-%d", chDate, i );
			sprintf( chDateBeg, "%s-%d-1", chDate, i );
			sprintf( chDateEnd, "%s-%d-%d", chDate, i, iMdays[i] );
		}
		
		// <> Find the first year/month in Account table
		if( "All" == csTmp ) 
		{
			CString		csFlow;
			m_cmbFlow.GetLBText( m_cmbFlow.GetCurSel(), csFlow );
			sprintf( chSQL, "SELECT SUM(Amount) FROM Account WHERE FlowClass='%s' AND Date >=#%s# AND Date <=#%s#", csFlow, chDateBeg, chDateEnd );
		}
		else
			sprintf( chSQL, "SELECT SUM(Amount) FROM Account WHERE Purpose='%s' AND Date >=#%s# AND Date <=#%s#", csTmp, chDateBeg, chDateEnd );
		
		try
		{
			m_pCommand->CommandText = chSQL;
			pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );
			
			if( !pRecSet->adoEOF )
			{
				var = pRecSet->GetCollect( (_variant_t)(long)0 );
				switch( var.vt ) 
				{
				case VT_I4:	// long
					dbSum = var.lVal;
					break ;
					
				case VT_R4: // float
					dbSum = var.fltVal;
					break ;
					
				case VT_R8: // double
					dbSum = var.dblVal;
					break ;
					
				default :
					dbSum = 0;
					break ;
				}

				// into flow chart
				m_chartMonth.AddValue( dbSum, chDateRange );
			}
			else
			{
				pRecSet->Close();
				return ;
			}
			
			pRecSet->Close();
		}
		catch(_com_error *e)
		{
			AfxMessageBox(e->ErrorMessage());
		}
	}	// end for{}
}

// 
// 
//--------------------------------------------------------------
void CDlgCountMonth::SetYear( DWORD	lyear )
{
	m_lYear = lyear;
}

// 
//--------------------------------------------------------------
void CDlgCountMonth::OnSelchangeCmbPurpose() 
{
	// Disable Search BTN when not focus in one label
	m_btnSaveSearch.EnableWindow( FALSE );
	

	// <> Count and into Chart
	CountOneYear();

	// ! Must after CountOneYear(), 
	// because using CNSChartCtrl::GetItemCount() in CountOutline()
	// <> info into readonly-edit
	CountOutline();

	// <> Do below to refresh ChartCtrl after "no values" to "has values" 
	//	  Otherwise ChartCtrl will not repaint() !
	m_chartMonth.SetChartStyle( NSCS_BAR );
}

// 
//--------------------------------------------------------------
void CDlgCountMonth::CountOutline()
{
	_RecordsetPtr	pRecSet;
	_variant_t		var;
	LONG			lCount = 0;
	DOUBLE			dbSum = 0;
	DOUBLE			dbAvg = 0;
	CHAR			chSQL[512] = { 0 };
	CHAR			chDate[50] = { 0 };
	CHAR			chDateBeg[50] = { 0 };
	CHAR			chDateEnd[50] = { 0 };
	CString			csTmp;
	
	
	m_cmbPurpose.GetLBText( m_cmbPurpose.GetCurSel(), csTmp );

	sprintf( chDate, "%d", m_lYear );
	strcpy( chDateBeg, chDate );
	strcpy( chDateEnd, chDate );
	// count by year
	if( wtkGetSysLanguage() == WTK_BIG5 ) 
	{
		strcat( chDateBeg, "/1/1" );
		strcat( chDateEnd, "/12/31" );
	}
	else
	{
		strcat( chDateBeg, "-01-01" );
		strcat( chDateEnd, "-12-31" );
	}
	
	// <> Compose SQL 
	if( "All" == csTmp ) 
	{
		CString		csFlow;
		m_cmbFlow.GetLBText( m_cmbFlow.GetCurSel(), csFlow );
		sprintf( chSQL, "SELECT SUM(Amount),COUNT(*) FROM Account WHERE FlowClass='%s' AND Date >=#%s# AND Date <=#%s#", csFlow, chDateBeg, chDateEnd );
	}
	else
		sprintf( chSQL, "SELECT SUM(Amount),COUNT(*) FROM Account WHERE Purpose='%s' AND Date >=#%s# AND Date <=#%s#", csTmp, chDateBeg, chDateEnd );

	try
	{
		m_pCommand->CommandText = chSQL;
		pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );
		
		if( !pRecSet->adoEOF )
		{
			var = pRecSet->GetCollect( (_variant_t)(long)0 );
			switch( var.vt ) 
			{
			case VT_I4:	// long
				dbSum = var.lVal;
				break ;
				
			case VT_R4: // float
				dbSum = var.fltVal;
				break ;
				
			case VT_R8: // double
				dbSum = var.dblVal;
				break ;
				
			default :
				dbSum = 0;
				break ;
			}
			
			var = pRecSet->GetCollect( (_variant_t)(long)1 );
			lCount = var.lVal;
			
			INT iMonth = m_chartMonth.GetItemCount();
			if( iMonth > 0 ) 
				dbAvg = dbSum/iMonth;
			else
				dbAvg = 0.0;
			
			// set text
			sprintf( chSQL, " Total of year: %.2f , Average of month: %.2f , Total records: %ld ", dbSum, dbAvg, lCount );
			m_edCountinfo.SetWindowText( chSQL );
		}
		
		pRecSet->Close();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
}


// 
//  For char
//--------------------------------------------------------------
void CDlgCountMonth::OnChartSelectedItem(NMHDR* pNMHDR, LRESULT* pResult)
{
	CString	csTmp;
	LPNMCHARTCTRL nmchart = (LPNMCHARTCTRL)pNMHDR;
	INT	iItem = nmchart->iItem;
	
	
	// <> m_csRecinfo
	csTmp = m_chartMonth.GetItemLabel( iItem );
	if( "NULL" == csTmp )
	{
		m_chMonth[0] = 0;
		// Disable Search BTN when not focus in one label
		m_btnSaveSearch.EnableWindow( FALSE );
	}
	else
	{
		strcpy( m_chMonth, csTmp );
		m_btnSaveSearch.EnableWindow( TRUE );
	}

	
	*pResult = FALSE;
}


// 
// "  Purpose='%s' AND date "
//--------------------------------------------------------------
void CDlgCountMonth::OnBtnToSearchView() 
{
	CDataFile		IniDF( MONEY_CFG );
	CString			csTmp;
	CHAR			chDateBeg[50] = { 0 };
	CHAR			chDateEnd[50] = { 0 };
	CHAR			chSQL[512] = { 0 };
						//	Month : 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12
	INT			i,	iMdays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	
	
	if( ( m_lYear % 4 == 0 && m_lYear % 100 != 0 ) 
		|| ( m_lYear % 400 == 0 ) )
	{
		// leap year, max date is 29
		iMdays[2]++;
	}
	
	m_cmbPurpose.GetLBText( m_cmbPurpose.GetCurSel(), csTmp );

	// compose month range
	if( strlen(m_chMonth) == 6 )	// "2005/7"
		memmove( m_chMonth, m_chMonth+5, 2 );
	else	// "2005/10" or "2005/07" 
		memmove( m_chMonth, m_chMonth+5, 3 );
	
	i = atoi( m_chMonth );

	if( wtkGetSysLanguage() == WTK_BIG5 ) 
	{
		sprintf( chDateBeg, "%d/%d/1", m_lYear, i );
		sprintf( chDateEnd, "%d/%d/%d", m_lYear, i, iMdays[i] );
	}
	else
	{
		sprintf( chDateBeg, "%d-%d-1", m_lYear, i );
		sprintf( chDateEnd, "%d-%d-%d", m_lYear, i, iMdays[i] );
	}

	if( "All" == csTmp ) 
	{
		CString		csFlow;
		m_cmbFlow.GetLBText( m_cmbFlow.GetCurSel(), csFlow );
		sprintf( chSQL, " FlowClass='%s' AND Date>=#%s# AND Date<=#%s#", csFlow, chDateBeg, chDateEnd );
	}
	else
		sprintf( chSQL, " Purpose='%s' AND Date>=#%s# AND Date<=#%s#", csTmp, chDateBeg, chDateEnd );
	
	
	IniDF.SetValue( "SQL", chSQL, "SQL segment for search", "SQL segment" );
	
	IniDF.Save();
	
	if( m_pSearchView )
		m_pSearchView->RefreshSearchView();
}

// 
// public interface for Dlg invoker
//--------------------------------------------------------------
void CDlgCountMonth::SetViewPtr(CSearchView *pView)
{
	if( pView != NULL ) 
		m_pSearchView = pView;
}
